package com.app.common.ex

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.os.Environment
import android.os.Process
import android.util.Log
import com.app.common.BuildConfig
import com.app.common.base.BaseApp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileNotFoundException
import java.io.PrintWriter
import java.io.StringWriter
import java.nio.charset.Charset
import java.text.SimpleDateFormat

const val LOG_TAG = "ThermoPro"
@SuppressLint("SimpleDateFormat")
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
const val logSaveLocal = false

fun logD(message: String) {
    Log.d("$LOG_TAG->", message)
    if (logSaveLocal || BuildConfig.DEBUG) {
        GlobalScope.launch {
            withContext(Dispatchers.IO) {
                try {
                    val file =
                        File(BaseApp.getInstance().cacheDir.absolutePath, "${LOG_TAG}_log.txt")
                    if (!file.exists()) {
                        file.createNewFile()
                    }
                    file.appendText(
                        dateFormat.format(System.currentTimeMillis()) + " " + message + "\r\n",
                        Charset.defaultCharset()
                    )
                }catch (e:Exception){
                    e.printStackTrace()
                }
            }
        }
    }
}

fun logD(exception: Exception) {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    exception.printStackTrace(pw)
    val message = sw.toString()
    Log.d("$LOG_TAG->", message)
    if (logSaveLocal || BuildConfig.DEBUG) {
        GlobalScope.launch {
            withContext(Dispatchers.IO) {
                try {
                    val file =
                        File(BaseApp.getInstance().cacheDir.absolutePath, "${LOG_TAG}_log.txt")
                    if (!file.exists()) {
                        file.createNewFile()
                    }
                    file.appendText(
                        dateFormat.format(System.currentTimeMillis()) + " " + message + "\r\n",
                        Charset.defaultCharset()
                    )
                }catch (e:Exception){
                    e.printStackTrace()
                }
            }
        }
    }
}

fun logE(message: String) {
    Log.e("$LOG_TAG->", message)
    if (logSaveLocal || BuildConfig.DEBUG) {
        GlobalScope.launch {
            withContext(Dispatchers.IO) {
                val file =
                    File(BaseApp.getInstance().cacheDir.absolutePath, "${LOG_TAG}_log.txt")
                if (!file.exists()) {
                    file.createNewFile()
                }
                file.appendText(
                    dateFormat.format(System.currentTimeMillis()) + " " + message + "\r\n",
                    Charset.defaultCharset()
                )
            }
        }
    }
}

fun logE(throwable: Throwable) {
    val stringWriter = StringWriter()
    val writer = PrintWriter(stringWriter)
    throwable.printStackTrace(writer)
    val buffer = stringWriter.buffer
    val message = buffer.toString()
    Log.e("$LOG_TAG->", message)
    if (logSaveLocal || BuildConfig.DEBUG) {
        GlobalScope.launch {
            withContext(Dispatchers.IO) {
                val file =
                    File(BaseApp.getInstance().cacheDir.absolutePath, "${LOG_TAG}_log.txt")
                if (!file.exists()) {
                    file.createNewFile()
                }
                file.appendText(
                    dateFormat.format(System.currentTimeMillis()) + " " + message + "\r\n",
                    Charset.defaultCharset()
                )
            }
        }
    }
}

fun logI(message: String) {
    Log.i("$LOG_TAG->", message)
    if (logSaveLocal || BuildConfig.DEBUG) {
        GlobalScope.launch {
            withContext(Dispatchers.IO) {
                val file =
                    File(BaseApp.getInstance().cacheDir.absolutePath, "$LOG_TAG.txt")
                if (!file.exists()) {
                    file.createNewFile()
                }
                file.appendText(
                    dateFormat.format(System.currentTimeMillis()) + " " + message + "\r\n",
                    Charset.defaultCharset()
                )
            }
        }
    }
}

class CatchException : Thread.UncaughtExceptionHandler {
    private var context: Context? = null
    var exceptionHandler: Thread.UncaughtExceptionHandler? = null
    fun attach(application: Application?) {
        context = application
        exceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
        Thread.setDefaultUncaughtExceptionHandler(this)
    }

    override fun uncaughtException(t: Thread, e: Throwable) {
        try {
            if (logSaveLocal || BuildConfig.DEBUG) {
                GlobalScope.launch {
                    withContext(Dispatchers.IO) {
                        val file =
                            File(
                                BaseApp.getInstance().cacheDir.absolutePath,
                                "${LOG_TAG}_log.txt"
                            )
                        if (!file.exists()) {
                            file.createNewFile()
                        }
                        val sw = StringWriter()
                        val pw = PrintWriter(sw)
                        e.printStackTrace(pw)
                        val message = sw.toString()
                        file.appendText(
                            dateFormat.format(System.currentTimeMillis()) + " " + message + "\r\n",
                            Charset.defaultCharset()
                        )
                    }
                }
            }
        } catch (e1: FileNotFoundException) {
            e1.printStackTrace()
        }
        if (exceptionHandler != null) {
            exceptionHandler!!.uncaughtException(t, e)
        }
        Process.killProcess(Process.myPid())
    }
}